package imageEditor.utility;

import imageEditor.mapEditor.MapPainer;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;

public class ImagePainer extends JPanel implements MouseListener, MouseMotionListener{
	
	private static final long serialVersionUID = 1L;
	public static final Color PLATFORM_COLOR = Color.BLUE;
	public static final Color GATE_COLOR = Color.RED;
	public static final Color STAIR_COLOR = Color.GREEN;
	private Image img;
	private Shape current;
	private boolean inside;
	private boolean onBorder;
	private Point start;
	private Point2d startPosition;
	private boolean canDraw;
	private boolean disable;
	private MapPainer painter;
	private Point2d pointerPosition;
	private Shape newShape;
	
	public ImagePainer(MapPainer mapPainer){
		super();
		
		painter=mapPainer;
		pointerPosition=new Point2d();
		setSize(800, 600);
		
		
		addMouseListener(this);
		addMouseMotionListener(this);
	}
	
	@Override
	public void paint(Graphics g) {
		if(img!=null){
			//Dimension d = getSize();
	  		//Insets i = getInsets();
	  		//g.drawi
	  		//g.drawImage(img, i.left, i.top, d.width - i.left - i.right, d.height - i.top - i.bottom, this );
			g.drawImage(img, 0, 0, this);
	  		
	  		for(Shape tmp:painter.getShapes()){
	  			if(tmp.isDeleted())
	  				continue;

	  			g.setColor(tmp.getColor());
	  			
				int x=tmp.getCenterX();
				int y=tmp.getCenterY();
				
				g.drawString(tmp.getMessage(), x, y);
				
	  			
				switch(tmp.getType()){
				case rectangle:
					g.drawRect(tmp.getX(),tmp.getY(),tmp.getHeight(),tmp.getWidth());
					break;
				case ellipse:
					g.drawOval(tmp.getX(),tmp.getY(),tmp.getHeight(),tmp.getWidth());
					break;
				}
				
				g.setColor(Color.BLACK);
				g.fillRect(tmp.getX(),tmp.getY(),10,10);
				g.setColor(Color.WHITE);
				g.drawString("X", tmp.getX(),tmp.getY()+10);
			}
	  		

			g.setColor(Color.BLACK);
			g.drawString(pointerPosition.toString(), 740, 590);
		}
	}
	
	public void setImage(Image i){
		img=i;
		canDraw=false;
		disable=false;
		repaint();
	}
	
	private void startDraw(Point p1) {
		if(!canDraw)
			return;
		
		Point2d p=new Point2d(p1);
		newShape.move(p);
		current=newShape;
		painter.getShapes().add(current);
		
		repaint();
	}
	
	private void isInside(Point p1, boolean set) {
		Point2d p=new Point2d(p1);
		
		for(Shape tmp:painter.getShapes()){
			if(tmp.isInside(p)){
				inside=true;
				if(set)
					current=tmp;
				return;
			}
		}
		
		inside=false;
	}
	
	private void isOnBorder(Point p1,boolean set) {
		Point2d p=new Point2d(p1);
		
		for(Shape tmp:painter.getShapes()){
			if(tmp.isOnBorder(p)){
				onBorder=true;
				if(set)
					current=tmp;
				return;
			}
		}
		
		onBorder=false;
	}
	
	private void remove(Point p1) {
		Point2d p=new Point2d(p1);
		
		for(Shape tmp:painter.getShapes()){
			if(tmp.isOnRemove(p)){
				painter.remove(tmp);
				tmp.delete();
				return;
			}
		}
		
		onBorder=false;
	}
	
	private void onDrag(Point end) {
		Point2d p=new Point2d(end);
		
		if(current!=null){
			current.resize(p);
		
			repaint();
		}
	}
	
	private void move(Point p1) {
		Point2d p=new Point2d(start,p1);
		p.plus(startPosition);
		
		
		if(current!=null){
			current.move(p);
		
			repaint();
		}
	}
	
	public void mouseClicked(MouseEvent arg0) {
		if(current!=null)
			startDraw(arg0.getPoint());
		else
			remove(arg0.getPoint());
		repaint();
	}
	
	public void mousePressed(MouseEvent arg0) {
		isOnBorder(arg0.getPoint(),true);
		isInside(arg0.getPoint(),true);
		
		start=arg0.getPoint();
		if(current!=null)
			startPosition=current.getPosition();
	}
	
	public void mouseReleased(MouseEvent arg0) {		
		/*int x=dim.width;
		int y=dim.height;
		
		setSize(x-1,y-1);
		
		setSize(x,y);
		
		current=null;
		
		setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));*/
		
		current=null;
		
		if(disable)
			canDraw=false;
	}
	
	public void mouseDragged(MouseEvent arg0) {
		if(inside){
			move(arg0.getPoint());
		}
		else{
			if(current==null)
				startDraw(arg0.getPoint());
		
			onDrag(arg0.getPoint());
		
			repaint();
		}
	}
	
	public void mouseMoved(MouseEvent arg0) {
		isInside(arg0.getPoint(),false);
		isOnBorder(arg0.getPoint(),false);
		
		pointerPosition=new Point2d(arg0.getPoint());
		
		if (onBorder)
			setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
		else if(inside)
			setCursor(new Cursor(Cursor.HAND_CURSOR));
		else
			setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
		
		repaint();
		
	}

	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void startDrawPlatform(Shape s) {
		canDraw=true;
		newShape=s;
	}

	public void startDrawGate(Shape sa) {
		canDraw=true;

		disable=true;
		
		newShape=sa;
	}

	public void startDrawStair(Shape s) {
		canDraw=true;
		newShape=s;
	}
}
